package com.carefree.bookmall.service.impl;

import com.carefree.bookmall.common.vo.OrderPayVo;
import com.carefree.bookmall.common.vo.PageVO;
import com.carefree.bookmall.dao.BookMapper;
import com.carefree.bookmall.dao.OrderMapper;
import com.carefree.bookmall.entity.Book;
import com.carefree.bookmall.entity.Order;
import com.carefree.bookmall.entity.OrderItem;
import com.carefree.bookmall.exception.CustomException;
import com.carefree.bookmall.service.OrderService;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Service;
import org.springframework.util.ObjectUtils;

import javax.annotation.Resource;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Date;
import java.util.List;

/**
 * @ClassName:OrderServiceImpl
 * @Description:
 * @Author Tengbin
 */
@Service(value = "orderService")
public class OrderServiceImpl implements OrderService {

    @Resource
    private OrderMapper orderMapper;

    @Resource
    private BookMapper bookMapper;


    /**
     * 添加订单信息
     *
     * @param order 订单信息
     * @return true or false
     */
    @Override
    public boolean addOrder(Order order) throws CustomException {

        if (ObjectUtils.isEmpty(order)) {
            throw new CustomException("未获取到需存储的订单信息，请检查后重试");
        }

        // 根据当前时间生成订单号
        String orderId = new SimpleDateFormat("yyyyMMddHHmmssSSS").format(new Date());
        order.setId(orderId);

        int orderRows = orderMapper.addOrder(order);
        String id = order.getId();

        order.getItemMap().forEach((key, value) -> {
            value.setOrderId(id);
            orderMapper.addOrderItem(value);
        });

        if (orderRows <= 0) {
            orderMapper.deleteOrder(orderId);
            orderMapper.deleteOrderItem(orderId);
            return false;
        }
        // 执行数据库操作
        return true;
    }

    /**
     * 根据用户id查询订单信息
     *
     * @param userId 用户id
     * @return 订单记录
     */
    @Override
    public List<Order> queryOrderByUserId(Integer userId) throws CustomException {
        if (userId == null) {
            throw new CustomException("未获取查询订单信息的必须参数");
        }
        // 根据用户id查询订单信息
        List<Order> orders = orderMapper.selectOrderByUserId(userId);
        // 根据订单id查询订单关联信息
        setOrderItemInfo(orders);
        return orders;
    }

    /**
     * 根据订单状态分页查询订单信息
     *
     * @param status     订单状态
     * @param pageNumber 页码
     * @return 分页对象
     */
    @Override
    public PageVO queryOrdersByStatus(Integer status, int pageNumber, int pageSize) {
        if (pageNumber <= 0) {
            pageNumber = 1;
        }

        // 实例化分页对象
        PageVO pageVO = new PageVO();
        // 初始化分页属性
        int totalCount = 0;
        List<Order> orders = Collections.emptyList();

        if (status != 1) {
            // 按订单状态查询
            totalCount = orderMapper.selectCountOfOrderByOstatus(status);
            orders = orderMapper.selectOrderByStatus(status, (pageNumber - 1) * pageSize, pageSize);
        } else {
            // 查询所有
            totalCount = orderMapper.selectCountOfOrder();
            orders = orderMapper.selectOrder((pageNumber - 1) * pageSize, pageSize);
        }
        // 根据订单id查询订单关联信息
        setOrderItemInfo(orders);

        // 为属性赋值
        pageVO.setPageNumber(pageNumber);
        pageVO.SetPageSizeAndTotalCount(pageSize, totalCount);
        pageVO.setList((List) orders);

        return pageVO;
    }


    /**
     * 修改订单状态
     *
     * @param orderId     订单id
     * @param orderStatus 修改后的订单状态
     * @return true or false
     */
    @Override
    public boolean updateOrderStatus(String orderId, Integer status) throws CustomException {
        if (orderId.isEmpty() || status < 0) {
            throw new CustomException("订单id或者订单状态必须不为空！");
        }
        return orderMapper.updateOrderStatus(orderId, status) > 0;
    }

    /**
     * 根据订单id删除订单信息
     *
     * @param orderId
     * @return true or false
     */
    @Override
    public boolean deleteOrderByOrderId(String orderId) throws CustomException {
        if (orderId.isEmpty()) {
            throw new CustomException("订单id必须不为空！");
        }

        int rows1 = orderMapper.deleteOrderItem(orderId);
        int rows2 = orderMapper.deleteOrder(orderId);

        if (rows1 <= 0 || rows2 <= 0) {
            throw new CustomException("订单信息删除失败！");
        }

        return true;
    }

    /**
     * 查询今日收入
     *
     * @return
     */
    @Override
    public Double queryTodayIncoming() {
        return orderMapper.selectIncoming();
    }


    /**
     * 查询订单总数
     *
     * @return
     */
    @Override
    public int queryOrderCounts() {
        return orderMapper.selectCountOfOrder();
    }


    /**
     * 删除指定用户指定的订单
     *
     * @param orderId
     * @param userId
     * @return
     */
    @Override
    public boolean removeOrderByIdAndUserId(String orderId, Integer userId) throws CustomException {

        if (StringUtils.isBlank(orderId) || userId == null) {
            throw new CustomException("订单号或者用户id必须不为空！");
        }

        int rows1 = orderMapper.updateOrderStatus(orderId, 0);

        if (rows1 <= 0) {
            throw new CustomException("订单状态修改失败！");
        }

        return true;
    }

    /**
     * 根据订单编号查询订单
     *
     * @param orderId
     * @return
     */
    @Override
    public Order queryOrderById(String orderId, Integer userId) throws CustomException {
        if (StringUtils.isBlank(orderId) || userId == null) {
            throw new CustomException("订单号必须不为空！");
        }
        return orderMapper.selectOrderById(orderId, userId);
    }

    /**
     * 修改订单（支付）
     *
     * @param orderId 订单号
     * @param paytype 支付类型
     * @param userId  用户id
     * @param status  订单状态（3：已付款）
     * @return
     */
    @Override
    public boolean modifyOrderByIdAndUserId(String orderId, Integer paytype, Integer status) throws CustomException {
        if (StringUtils.isBlank(orderId) || paytype == null) {
            throw new CustomException("付款的必要参数不能为空！");
        }

        List<OrderItem> orderItems = orderMapper.selectOrderItemByOrderId(orderId);
        for (OrderItem orderItem : orderItems) {
            Book book = bookMapper.selectBookByBookId(orderItem.getBookId());
            book.setStock(book.getStock() - orderItem.getAmount());
            bookMapper.modifyBook(book);
        }

        return orderMapper.updateOrderByIdAndUserId(orderId, paytype, status) > 0;
    }

    /**
     * 查询订单支付信息
     *
     * @param orderId 订单号
     * @param userId  用户id
     * @return
     */
    @Override
    public OrderPayVo queryOrderPayInfo(String orderId, Integer userId) throws CustomException {

        if (orderId.isEmpty() || userId == null) {
            throw new CustomException("需支付的订单号为空或用户信息为空！");
        }

        // 初始化
        List<String> subjects = new ArrayList<>();
        OrderPayVo orderPayVo = new OrderPayVo();
        // 查询订单基本信息
        Order order = orderMapper.selectOrderById(orderId, userId);

        // 查询订单关联信息
        List<OrderItem> orderItems = orderMapper.selectOrderItemByOrderId(orderId);
        for (OrderItem orderItem : orderItems) {
            // 查询商品名称
            String bookName = bookMapper.selectNameById(orderItem.getBookId());
            subjects.add(bookName);
        }
        // 为自定义对象赋值
        orderPayVo.setOutTradeNo(orderId);
        orderPayVo.setTotalAmount(order.getTotal());
        if (subjects.size() >= 3) {
            orderPayVo.setSubject(subjects.get(0) + "等书籍");
        } else {
            orderPayVo.setSubject(subjects.toString());
        }

        return orderPayVo;
    }

    /**
     * 根据订单id查询订单关联信息
     *
     * @param orders
     */
    private void setOrderItemInfo(List<Order> orders) {
        for (int i = 0; i < orders.size(); i++) {
            // 根据订单id查询订单关联信息
            orders.get(i).setItemList(orderMapper.selectOrderItemByOrderId(orders.get(i).getId()));
            for (int j = 0; j < orders.get(i).getItemList().size(); j++) {
                orders.get(i).getItemList().get(j).setBook(bookMapper.selectBookByBookId(orders.get(i).getItemList().get(j).getBookId()));
            }
        }
    }
}
